<template>
	<div class="tree-component">
		<div v-for="(item, index) in tree" :key="index" class="tree-node">
			<!-- 节点内容 -->
			<div class="tree-item" :style="{ marginLeft: `${treeListIndex * 20}px` }">
				<!-- 展开/收起图标 -->
				<div v-if="item.children?.length" class="tree-toggle" @click="toggleNode(index)">
					<van-icon :name="item.open ? 'arrow-down' : 'arrow'" :class="{ expanded: item.open }" />
				</div>
				<div v-else class="tree-toggle-placeholder"></div>

				<!-- 节点内容 -->
				<div class="tree-content" @click="handleSelect(item, index)">
					<!-- 选择框 -->
					<template v-if="isChoice ? !item.children : true">
						<van-checkbox :value="item.checked === 1" :indeterminate="item.checked === -1"
							@click.native.stop />
					</template>

					<!-- 节点标题 -->
					<span class="tree-title" :class="{ 'is-selected': item.checked === 1 }">
						{{ item.label }}
					</span>
				</div>
			</div>

			<!-- 子节点递归 -->
			<tree-select v-if="item.children?.length && item.open" :data-parent="item" :data-tree="item.children"
				:is-open-all="isOpenAll" :is-choice="isChoice" :tree-list-index="treeListIndex + 1"
				@select="handleChildSelect($event, item)" />
		</div>
	</div>
</template>

<script>
	import {
		Icon,
		Checkbox
	} from 'vant'


	export default {
		name: 'TreeSelect',

		components: {
			[Icon.name]: Icon,
			[Checkbox.name]: Checkbox
		},


		props: {
			isChoice: {
				type: Boolean,
				default: false
			},
			dataTree: {
				type: Array,
				default: () => []
			},
			treeListIndex: {
				type: Number,
				default: 1
			},
			isOpenAll: {
				type: Boolean,
				default: false
			}
		},

		data() {
			return {
				tree: [],
				allChoiceList: []
			}
		},

		watch: {
			dataTree: {
				handler(newVal) {
					this.tree = this.initTreeData(newVal)
				},
				immediate: true
			}
		},

		methods: {
			// 初始化树数据
			initTreeData(nodes) {
				return nodes.map(node => ({
					...node,
					checked: node.checked ?? 0,
					open: this.isOpenAll,
					children: node.children?.length ?
						this.initTreeData(node.children) : undefined
				}))
			},

			// 切换节点展开状态
			toggleNode(index) {
				this.$set(this.tree[index], 'open', !this.tree[index].open)
			},

			// 处理节点选择
			handleSelect(item, index) {
				if (this.isChoice && String(item.id).includes('#')) {
					return
				}

				const updatedItem = this.handleNodeCheck(item)
				this.updateTree(updatedItem)
				this.emitSelect(updatedItem)
			},

			// 处理节点选中状态
			handleNodeCheck(node) {
				const newNode = {
					...node
				}

				switch (newNode.checked) {
					case 0:
						newNode.checked = 1
						if (newNode.children?.length) {
							newNode.children = this.setAllChildrenChecked(newNode.children, true)
						}
						break
					case 1:
						newNode.checked = 0
						if (newNode.children?.length) {
							newNode.children = this.setAllChildrenChecked(newNode.children, false)
						}
						break
					default:
						newNode.checked = 1
						if (newNode.children?.length) {
							newNode.children = this.setAllChildrenChecked(newNode.children, true)
						}
				}

				return newNode
			},

			// 更新树数据
			updateTree( newItem) {
				const updateNode = (tree) => {
					if (this.isChoice) {
						tree = this.setAllChildrenChecked(tree, false)
					}
					return tree.map(node => {
						if (node.id === newItem.id) {
							return newItem
						}
						if (node.children?.length) {
							return {
								...node,
								children: updateNode(node.children)
							}
						}
						return node
					})
				}
				this.tree = updateNode(this.tree)
			},

			// 设置所有子节点选中状态
			setAllChildrenChecked(nodes, checked) {
				return nodes.map(node => ({
					...node,
					checked: checked ? 1 : 0,
					children: node.children?.length ?
						this.setAllChildrenChecked(node.children, checked) : []
				}))
			},

			// 获取子节点状态
			getChildrenState(nodes) {
				const state = nodes.reduce((acc, node) => {
					if (node.checked === 1 || node.checked === -1) {
						acc.none = false
					}
					if (node.checked === 0 || node.checked === -1) {
						acc.all = false
					}
					return acc
				}, {
					all: true,
					none: true
				})

				return {
					...state,
					half: !state.all && !state.none
				}
			},

			// 处理子节点选择
			handleChildSelect(event, parent) {
				const {
					item
				} = event.detail
				const updatedParent = {
					...parent
				}

				// updatedParent.children = this.updateTree(updatedParent.children, item)
				// const state = this.getChildrenState(updatedParent.children)
				// updatedParent.checked = state.half ? -1 : (state.all ? 1 : 0)
				this.updateTree( item)
				this.emitSelect(item)
			},

			// 发送选择事件
			emitSelect(item) {
				this.allChoiceList = this.getAllCheckedNodes(this.tree)
				this.$emit('select', {
					detail: {
						item,
						list: this.allChoiceList
					}
				})
			},

			// 获取所有选中节点
			getAllCheckedNodes(nodes, result = []) {
				nodes.forEach(node => {
					if (node.checked === 1 && !String(node.id).includes('#')) {
						result.push(node)
					}
					if (node.children?.length) {
						this.getAllCheckedNodes(node.children, result)
					}
				})
				return result
			}
		}
	}
</script>

<style lang="scss" scoped>
	.tree-component {
		background: #fff;
		overflow: auto;
	}

	.tree-node {
		.tree-item {
			display: flex;
			align-items: center;
			padding: 5px 0;
		}

		.tree-toggle {
			width: 20px;
			display: flex;
			justify-content: center;
			align-items: center;
			cursor: pointer;

			.van-icon {
				transition: transform 0.3s;

				&.expanded {
					transform: rotate(90deg);
				}
			}
		}

		.tree-toggle-placeholder {
			width: 20px;
		}

		.tree-content {
			display: flex;
			align-items: center;
			flex: 1;
			cursor: pointer;

			.van-checkbox {
				margin-right: 12px;
			}
		}

		.tree-title {
			font-size: 14px;
			color: #1c2438;
			word-break: break-all;

			&.is-selected {
				color: #1989fa;
			}
		}
	}
</style>